package src.NPCs;

import src.Main;
import src.Players.Player;

public class NPCAttack
{
    private NPC n;

    public NPCAttack(NPC _n)
    {
        n = _n;
    }

    public void attackPlayer()
    {
        if(n == null)
        {
            return;
        }
        if(!canAttackPlayer())
        {
            resetAttack();
            return;
        }
        Player p = Main.m.ge.players[n.killingPlayerId];
        n.requestFaceCoords(p.absX, p.absY);
        if(n.atkType == 0 && Main.m.ge.getDistance(p.absX, p.absY, n.absX, n.absY) != 1)
        {
            followPlayer(p);
            return;
        }
        if(n.combatDelay <= 0)
        {
            int hitDiff = 0;
            if(n.atkType == 0)
            {
                switch(n.npcType)
                {
                    default:
                        n.requestAnim(getMeleeAttackAnimation(n), 0);
                        hitDiff = random(n.maxHit);
                        p.appendHit(hitDiff, 0);
                        n.combatDelay = getAttackSpeed();
                    break;
                }
            }
            else if(n.atkType == 1)
            {
                switch(n.npcType)
                {
                    default:
                        n.requestAnim(getRangedAttackAnimation(), 0);
                        hitDiff = random(n.maxHit);
                        p.appendHit(hitDiff, 0);
                        n.combatDelay = getAttackSpeed();
                    break;
                }
            }
            else if(n.atkType == 2)
            {
                switch(n.npcType)
                {
                    default:
                        n.requestAnim(getMageAttackAnimation(), 0);
                        hitDiff = random(n.maxHit);
                        p.appendHit(hitDiff, 0);
                        n.combatDelay = getAttackSpeed();
                    break;
                }
            }
        }
    }

    private int getMove(int Place1, int Place2)
    {
        if ((Place1 - Place2) == 0)
            return 0;
        else
        if ((Place1 - Place2) < 0)
            return 1;
        else
        if ((Place1 - Place2) > 0)
            return -1;
        return 0;
    }

    public void followPlayer(Player p)
    {
        if(p == null)
        {
            return;
        }
        int pX = p.absX;
        int pY = p.absY;
        if(pY < n.absY && pX == n.absX)
        {
            n.moveX = 0;
            n.moveY = getMove(n.absY, pY + 1);
        }
        else if(pY > n.absY && pX == n.absX)
        {
            n.moveX = 0;
            n.moveY = getMove(n.absY, pY - 1);
        }
        else if(pX < n.absX && pY == n.absY)
        {
            n.moveX = getMove(n.absX, pX + 1);
            n.moveY = 0;
        }
        else if(pX > n.absX && pY == n.absY)
        {
            n.moveX = getMove(n.absX, pX - 1);
            n.moveY = 0;
        }
        else if(pX < n.absX && pY < n.absY)
        {
            n.moveX = getMove(n.absX, pX + 1);
            n.moveY = getMove(n.absY, pY + 1);
        }
        else if(pX > n.absX && pY > n.absY)
        {
            n.moveX = getMove(n.absX, pX - 1);
            n.moveY = getMove(n.absY, pY - 1);
        }
        else if(pX < n.absX && pY > n.absY)
        {
            n.moveX = getMove(n.absX, pX + 1);
            n.moveY = getMove(n.absY, pY - 1);
        }
        else if(pX > n.absX && pY < n.absY)
        {
           n.moveX = getMove(n.absX, pX - 1);
           n.moveY = getMove(n.absY, pY + 1);
        }
        Main.m.ge.moveN.getNextNPCMovement(n);
    }

    public int getAttackSpeed()
    {
        if(n == null)
        {
            return 6;
        }
        switch(n.npcType)
        {
            default:
                return 6;
        }
    }

    public static int getMeleeAttackAnimation(NPC _n)
    {
        if(_n == null)
        {
            return 451;
        }
        switch(_n.npcType)
        {
            case 1:
            case 2:
            case 3:
            case 34:
            case 1714:
                return 422; //Human punch.
            case 4:
            case 5:
            case 6:
            case 1715:
                return 423; //Human kick.
            case 7:
                return 408; //Sythe.
            case 187:
            case 1904:
            case 1905:
                return 412; //Dagger stab.
            default:
                return 451; //Sword slash.
        }
    }

    public int getRangedAttackAnimation()
    {
        if(n == null)
        {
            return 451;
        }
        switch(n.npcType)
        {
            default:
                return 451;
        }
    }

    public int getMageAttackAnimation()
    {
        if(n == null)
        {
            return 451;
        }
        switch(n.npcType)
        {
            default:
                return 451;
        }
    }

    public static int getDeathAnimation(int nId)
    {
        switch(nId)
        {
            default:
                return 2304;
        }
    }

    public void resetAttack()
    {
        if(n == null)
        {
            return;
        }
        n.isUnderPlayerAttack = false;
        n.killingPlayerId = 0;
        n.randomWalk = true;
    }

    public static int random(int range)
    {
        return (int)(Math.random() * (range + 1));
    }

    public boolean canAttackPlayer()
    {
        if(n == null || n.isDead)
        {
            return false;
        }
        else if(n.killingPlayerId < 1 || n.killingPlayerId >= Main.m.ge.maxPlayers || Main.m.ge.players[n.killingPlayerId] == null)
        {
            return false;
        }
        Player p = Main.m.ge.players[n.killingPlayerId];
        if(p.skillLvl[3] <= 0 || p.isDead || n.isDead)
        {
            return false;
        }
        if(Main.m.ge.getDistance(p.absX, p.absY, n.absX, n.absY) > 8)
        {
            return false;
        }
        return true;
    }
}